<?php

namespace App\Console\Scripts\Counter;

use App\Consts\GlobalConst;
use App\Consts\GlobalCounterConst;
use App\Consts\GlobalPackageConst;
use App\Models\Cache\CacheKey;
use App\Models\SysArticle;
use App\Models\SysNote;
use App\Models\UserCollect;
use App\Models\UserCollectPackage;
use Illuminate\Database\Query\Builder;

/**
 * 收藏夹计数统计脚本
 * Class ArticleCounterCommand
 * @package App\Console\Scripts\Counter
 */
class PackageCounterCommand extends BaseCounterCommand
{

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'counter:package {action}';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'counter for package';

    /**
     * 收藏夹私密内容统计
     * [!] 被删除数 + 被私密数
     * @return int
     */
    public function collectSelf()
    {
        $subMode = $this->_getPackageSubModel();
        $finish = $subMode->count();
        // 每 100 单位合并处理一次
        $subMode->chunkById(100, function ($list) use ($finish) {
            foreach ($list as $item) {
                static $index = 1;
                $id = $item->collect_package_id;
                $collectList = UserCollect::getSubModel(function (Builder $query) use ($id) {
                    $query->where('package_id', $id);
                    $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
                }, ['id', 'package_id', 'user_id', 'target_id', 'target_type'])->get();
                $total = 0;
                foreach ($collectList as $collect) {
                    $targetType = $collect->target_type;
                    $targetId = $collect->target_id;
                    if ($targetType == GlobalConst::TARGET_TYPE_ARTICLE) {
                        $tmp = SysArticle::getSubModel(function (Builder $query) use($targetId) {
                            $query->where('article_id', $targetId);
                            $query->where(function ($query) {
                                $query->where('is_deleted', GlobalConst::IS_DELETED)
                                    ->orWhere(['is_shield'  =>  GlobalConst::IS_SHIELD]);
                            });
                        })->count();
                        if ($tmp) $total++;
                    } elseif ($targetType == GlobalConst::TARGET_TYPE_NOTE) {
                        $tmp = SysNote::getSubModel(function (Builder $query) use($targetId) {
                            $query->where('note_id', $targetId);
                            $query->where(function ($query) {
                                $query->where('is_deleted', GlobalConst::IS_DELETED)
                                    ->orWhere(['is_public'  =>  GlobalPackageConst::IS_NOT_PUBLIC])
                                    ->orWhere(['is_shield'  =>  GlobalConst::IS_SHIELD]);
                            });
                        })->count();
                        if ($tmp) $total++;
                    }
                }
                // set cache
                $cacheKey = $this->setHashCache(
                    ['package_id' => $id],
                    CacheKey::COUNTER_COLLECT_PACKAGE,
                    [GlobalCounterConst::COUNT_COLLECT_PACKAGE_CONTENT_PRIVATE => $total]
                );
                // log info
                $info = "[$index/$finish] set cache key `$cacheKey` - ".GlobalCounterConst::COUNT_COLLECT_PACKAGE_CONTENT_PRIVATE." {$this->sort} to (int) $total";
                $this->info($info);
                if ($total) $this->logger($info, false, 'script');
                $index++;
            }
        }, 'collect_package_id');
        return 1;
    }

    /**
     * 收藏夹内容统计
     * [!] 更新表，非缓存
     * @return int
     */
    public function collectTotal()
    {
        $subMode = $this->_getPackageSubModel();
        $finish = $subMode->count();
        // 每 100 单位合并处理一次
        $subMode->chunkById(100, function ($list) use ($finish) {
            foreach ($list as $item) {
                static $index = 1;
                $id = $item->collect_package_id;
                $userId = $item->user_id;
                $total = UserCollect::getSubModel(function (Builder $query) use ($id) {
                    $query->where('package_id', $id);
                    $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
                }, ['id'])->count();
                // update collect total
                UserCollectPackage::getModel($userId)
                    ->where('user_id', $userId)
                    ->where('collect_package_id', $id)->update([
                        'total' => $total ? : 0
                ]);
                // log info
                $tableName = UserCollectPackage::getTableNameById($userId);
                $info = "[$index/$finish] update `{$tableName}` - pid  = {$id}  {$this->sort} `total` to (int) $total";
                $this->info($info);
                if ($total) $this->logger($info, false, 'script');
                $index++;
            }
        }, 'collect_package_id');
        return 1;
    }

    /**
     * get sub model
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|mixed
     */
    private function _getSubModel()
    {
        $subMode = UserCollect::getSubModel(function (Builder $query) {
            $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
        }, ['id', 'package_id', 'user_id', 'target_id', 'target_type']);
        return $subMode;
    }

    /**
     * get sub model
     * @return \Illuminate\Database\Eloquent\Builder|\Illuminate\Database\Eloquent\Model|mixed
     */
    private function _getPackageSubModel()
    {
        $subMode = UserCollectPackage::getSubModel(function (Builder $query) {
            $query->where('is_deleted', GlobalConst::IS_NOT_DELETE);
        }, ['id', 'collect_package_id', 'user_id']);
        return $subMode;
    }

}
